// 序列化工具

export interface SerializerOptions {
  compress?: boolean;
  encoding?: 'utf8' | 'base64';
  maxSize?: number;
}

export class Serializer {
  private options: SerializerOptions;

  constructor(options: SerializerOptions = {}) {
    this.options = {
      compress: false,
      encoding: 'utf8',
      maxSize: 1024 * 1024, // 1MB
      ...options,
    };
  }

  /**
   * 序列化数据
   */
  serialize(data: any): string {
    try {
      let serialized = JSON.stringify(data);

      // 检查大小限制
      if (this.options.maxSize && Buffer.byteLength(serialized) > this.options.maxSize) {
        throw new Error(`Serialized data exceeds maximum size of ${this.options.maxSize} bytes`);
      }

      // 压缩处理
      if (this.options.compress) {
        serialized = this.compress(serialized);
      }

      // 编码处理
      if (this.options.encoding === 'base64') {
        serialized = Buffer.from(serialized).toString('base64');
      }

      return serialized;
    } catch (error) {
      throw new Error(
        `Serialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * 反序列化数据
   */
  deserialize<T = any>(data: string): T {
    try {
      let processed = data;

      // 解码处理
      if (this.options.encoding === 'base64') {
        processed = Buffer.from(processed, 'base64').toString('utf8');
      }

      // 解压缩处理
      if (this.options.compress) {
        processed = this.decompress(processed);
      }

      return JSON.parse(processed) as T;
    } catch (error) {
      throw new Error(
        `Deserialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * 检查数据是否为序列化格式
   */
  isSerializedData(data: string): boolean {
    try {
      if (this.options.encoding === 'base64') {
        // 检查是否为有效的base64
        const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
        if (!base64Regex.test(data)) {
          return false;
        }
        data = Buffer.from(data, 'base64').toString('utf8');
      }

      if (this.options.compress) {
        data = this.decompress(data);
      }

      JSON.parse(data);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 获取序列化后的大小
   */
  getSerializedSize(data: any): number {
    const serialized = this.serialize(data);
    return Buffer.byteLength(serialized);
  }

  /**
   * 简单压缩实现（实际项目中可以使用更好的压缩算法）
   */
  private compress(data: string): string {
    // 这里使用简单的压缩策略，实际项目中可以使用 zlib 等
    return data;
  }

  /**
   * 简单解压缩实现
   */
  private decompress(data: string): string {
    // 对应的解压缩实现
    return data;
  }
}

// 默认序列化器实例
export const defaultSerializer = new Serializer();

// 压缩序列化器实例
export const compressedSerializer = new Serializer({
  compress: true,
  encoding: 'base64',
});

/**
 * 智能序列化 - 根据数据类型自动选择序列化策略
 */
export function smartSerialize(data: any): string {
  // 如果是字符串且不是JSON，直接返回
  if (typeof data === 'string' && !isJsonString(data)) {
    return data;
  }

  // 如果是数字，转换为字符串
  if (typeof data === 'number') {
    return data.toString();
  }

  // 如果是布尔值，转换为字符串
  if (typeof data === 'boolean') {
    return data.toString();
  }

  // 其他类型使用JSON序列化
  return defaultSerializer.serialize(data);
}

/**
 * 智能反序列化 - 尝试恢复原始数据类型
 */
export function smartDeserialize<T = any>(data: string): T {
  // 尝试解析为数字
  const num = Number(data);
  if (!isNaN(num) && isFinite(num) && data.trim() === num.toString()) {
    return num as T;
  }

  // 尝试解析为布尔值
  if (data === 'true') return true as T;
  if (data === 'false') return false as T;

  // 尝试JSON反序列化
  if (isJsonString(data)) {
    try {
      return defaultSerializer.deserialize<T>(data);
    } catch {
      // 如果JSON解析失败，返回原字符串
      return data as T;
    }
  }

  // 返回原字符串
  return data as T;
}

/**
 * 检查字符串是否为JSON格式
 */
function isJsonString(str: string): boolean {
  try {
    JSON.parse(str);
    return true;
  } catch {
    return false;
  }
}
